package com.basic.library.brvah;

import androidx.annotation.NonNull;

import com.basic.library.utils.MyLog;
import com.chad.library.adapter.base.entity.AbstractExpandableItem;
import com.chad.library.adapter.base.entity.IExpandable;
import com.chad.library.adapter.base.entity.MultiItemEntity;

import java.util.Collection;
import java.util.List;

/**
 * @author jiangyun
 * @description 多布局适配器(支持列表 + 网格混排)
 * 混排时！！！getItemType < 0 ,是 整行显示
 * @time 创建时间：2018/4/2 13:27
 */
public abstract class MyBaseMultiExpandItemQuickAdapter<T extends MultiItemEntity, K extends MBaseViewHolder>
        extends MyBaseMultiItemQuickAdapter<T, K> {

    public MyBaseMultiExpandItemQuickAdapter(int[] layoutResId) {
        super(layoutResId);
    }

    public MyBaseMultiExpandItemQuickAdapter(int[] layoutResId, int[] mVariableId) {
        super(layoutResId, mVariableId);
    }

    public MyBaseMultiExpandItemQuickAdapter(int[] types, int[] layoutResId, int[] mVariableId) {
        super(types, layoutResId, mVariableId);
    }

    public MyBaseMultiExpandItemQuickAdapter(List<T> data, int[] layoutResId) {
        super(data, layoutResId);
    }

    public MyBaseMultiExpandItemQuickAdapter(int[] types, List<T> data, int[] layoutResId) {
        super(types, data, layoutResId);
    }

    @Override
    public void addData(@NonNull T data) {
        if (data instanceof IExpandable) {
            super.addData(data);
//            expand(mData.size());
//            expandAll1();
        } else {
            IExpandable iExpandable = addDataToParent(mData.size() - 1, data);
            super.addData(data);
            iExpandable.setExpanded(true);
        }
    }

    @Override
    public void addData(@NonNull Collection<? extends T> newData) {
        boolean isIExpandable = false;
        for (T newDatum : newData) {
            isIExpandable = (newDatum instanceof IExpandable) || isIExpandable;
        }
        if (isIExpandable) {
            super.addData(newData);
//            expandAll1();
        } else {
            IExpandable iExpandable = addAllDataToParent(mData.size() - 1, newData);
            super.addData(newData);
            iExpandable.setExpanded(true);
        }
    }

    public void addData(@NonNull Collection<? extends T> newData, boolean isExpand) {
        boolean isIExpandable = false;
        for (T newDatum : newData) {
            isIExpandable = (newDatum instanceof IExpandable) || isIExpandable;
        }
        if (isIExpandable) {
            super.addData(newData);
            if (isExpand)
                expandAll1();
        } else {
            IExpandable iExpandable = addAllDataToParent(mData.size() - 1, newData);
            super.addData(newData);
            iExpandable.setExpanded(true);
        }
    }

    @Override
    public void addData(int position, @NonNull T data) {
        if (data instanceof IExpandable) { //position必须是AbstractExpandableItem的位置，或是头和尾
            super.addData(position, data);
//            expand(position);
//            expandAll1();
        } else {
            IExpandable iExpandable = addDataToParent(position, data);
            super.addData(position, data);
            iExpandable.setExpanded(true);
        }
    }

    /**
     * @param position 应该不会是负数吧 ！！！！！
     *                 如果newData是子subItems，那position需要传的是父position+1
     * @param newData
     */
    @Override
    public void addData(int position, @NonNull Collection<? extends T> newData) {
        boolean isIExpandable = false;
        for (T newDatum : newData) {
            isIExpandable = (newDatum instanceof IExpandable) || isIExpandable;
        }
        if (isIExpandable) {
            super.addData(position, newData);
//            expandAll1();
        } else {
            IExpandable iExpandable = addAllDataToParent(position, newData);
            super.addData(position, newData);
            iExpandable.setExpanded(true);
        }
    }

    @Override
    public void remove(int position) {
        T data = mData.get(position);
        if (data instanceof IExpandable) {
            IExpandable expandable = (IExpandable) data;
            if (expandable.getSubItems() == null) {
                super.remove(position);
                return;
            }
            int subSize = expandable.getSubItems().size();
            int internalPosition = position + getHeaderLayoutCount();
            if (internalPosition + subSize >= internalPosition) {
                mData.subList(internalPosition, internalPosition + subSize + 1).clear();
            }
            expandable.getSubItems().clear();
            notifyItemRangeRemoved(internalPosition, subSize + 1);
//            notifyItemRangeChanged(internalPosition, subSize + 1); //有问题，见鬼
            notifyItemRangeChanged(internalPosition, mData.size() - internalPosition);
        } else {
//            removeDataFromParent(position);
            super.remove(position);
        }
    }

    @Override
    protected void removeDataFromParent(T child) {
//        if (child instanceof IExpandable) return;
        int position = getItemPosition(child);
        int parentPosition = getParentPositionWithChildPosition(child);
        if (position >= 0) {
            IExpandable parent = (IExpandable) mData.get(parentPosition);
            if (parent.getSubItems() != null && parent.getSubItems().contains(child)) {
                boolean a = parent.getSubItems().remove(parent.getSubItems().get(position - parentPosition - 1));
                MyLog.p("移除了：" + a + " ;ParentPosition：" + parentPosition + " ;childPosition：" + position);
            }
        }
    }

    /**
     * 移除子控件时，移除父控件实体类中相关子控件数据，避免关闭后再次展开数据重现
     */
    protected void removeDataFromParent(int position) {
        int parentPosition = getParentPositionWithChildPosition(position);
        if (position >= 0) {
            IExpandable parent = (IExpandable) mData.get(parentPosition);
            boolean a = parent.getSubItems().remove(parent.getSubItems().get(position - parentPosition - 1));
            MyLog.p("移除：" + a + " ;ParentPosition：" + parentPosition + " ;childPosition：" + position);
        }
    }

    protected IExpandable addDataToParent(int childPosition, T newChild) {
        int position = getParentPositionWithChildPosition(childPosition);
        IExpandable parent;
        if (position >= 0) {
            parent = (IExpandable) mData.get(position);
            parent.getSubItems().add(newChild);
            MyLog.p("添加：" + true + " ;ParentPosition：" + position + " ;childPosition：" + childPosition);
        }
        return null;
    }


    protected IExpandable addAllDataToParent(int childPosition, Collection<? extends T> newData) {
        int position = getParentPositionWithChildPosition(childPosition); //不知道为啥，用getParentPosition返回的不对
        IExpandable parent = (IExpandable) mData.get(position);
        if (position >= 0) {
            if (parent.getSubItems() == null && parent instanceof AbstractExpandableItem) {
                AbstractExpandableItem aei = (AbstractExpandableItem) parent;
                aei.addSubItem(null);
                aei.getSubItems().clear();
            }
            parent.getSubItems().addAll(childPosition - position - 1, newData);
            MyLog.p("添加复数" + newData.size() + "个：" + true + " ;ParentPosition：" + position + " ;childPosition：" + childPosition);
        }
        return parent;
    }

    public void notifyItemChangedX(int position) {
        notifyItemChanged(position + getHeaderLayoutCount());
    }

    public IExpandable getParent(int position) {
        position = getParentPositionWithChildPosition(position);
        if (position >= 0) {
            IExpandable parent = (IExpandable) mData.get(position);
            return parent;
        }
        return null;
    }

    /**
     * @param position
     * @return 根据position获取父实体类（实现IExpandable接口）在mData中的位置
     */
    public int getParentPositionWithChildPosition(int position) {
        if (mData.size() <= position) { //越界情况（对应情况 - 插入整个列表的尾部时）
            position = position - 1;
        } else {
            //position对应的实体本身就是IExpandable类型；找上一个
            // （对应情况 - 插入某个IExpandable尾部时,position ==下一个IExpandable的位置）
            T item = mData.get(position);
            if (item instanceof IExpandable)
                position = position - 1;
        }
        for (int i = position; i >= 0; i--) {
            T temp = mData.get(i);
            if (temp instanceof IExpandable) {
                IExpandable expandable = (IExpandable) temp;
                return i;
            }
        }
        return -1;
    }

    public int getParentPositionWithChildPosition(T item) {
        int position = getItemPosition(item);
        if (mData.size() <= position) { //越界情况（对应情况 - 插入整个列表的尾部时）
            position = position - 1;
        } else {
            //position对应的实体本身就是IExpandable类型；找上一个
            // （对应情况 - 插入某个IExpandable尾部时,position ==下一个IExpandable的位置）
//            T item = mData.get(position);
            if (item instanceof IExpandable)
                position = position - 1;
        }
        for (int i = position; i >= 0; i--) {
            T temp = mData.get(i);
            if (temp instanceof IExpandable) {
                IExpandable expandable = (IExpandable) temp;
                return i;
            }
        }
        return -1;
    }

    @Override
    public int getParentPosition(@NonNull T item) {
        int position = getItemPosition(item);

        if (position == -1) {
            return -1;
        }

        // if the item is IExpandable, return a closest IExpandable item position whose level smaller than this.
        // if it is not, return the closest IExpandable item position whose level is not negative
        int level;
        if (item instanceof IExpandable) {
            level = ((IExpandable) item).getLevel();
        } else {
            level = Integer.MAX_VALUE;
        }
        if (level == 0) {
            return position;
        } else if (level == -1) {
            return -1;
        }

        for (int i = position; i >= 0; i--) {
            T temp = mData.get(i);
            if (temp instanceof IExpandable) {
                IExpandable expandable = (IExpandable) temp;
                if (expandable.getLevel() >= 0 && expandable.getLevel() < level) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 全部展开
     */
    public void expandAll1() {
        for (int i = mData.size() - 1; i >= 0; i--) {
            T item = mData.get(i);
            if (item instanceof IExpandable) {
                IExpandable expandable = (IExpandable) item;
//                expand(i);
                if (!expandable.isExpanded()
                        /*&& expandable.getSubItems() != null
                        && expandable.getSubItems().size() != 0*/)
                    expand(i + getHeaderLayoutCount());
            }
        }
    }

    /**
     * 三方库里的有问题
     *
     * @param item
     * @return
     */
    private int getItemPosition(T item) {
        int position = 0;
        for (int i = 0; i < mData.size(); i++) {
            if (mData.get(i) == item) {
                position = i;
                break;
            }
        }
        return item != null && mData != null && !mData.isEmpty() ? position : -1;
    }

    public void scrollToPosition(int position) {
        if (getRecyclerView() != null)
            getRecyclerView().scrollToPosition(position);
    }

    public void smoothScrollToPosition(int position) {
        if (getRecyclerView() != null)
            getRecyclerView().smoothScrollToPosition(position);
    }
}